/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.valarnin.plugins.citygen.generator;

import com.valarnin.plugins.citygen.Direction;
import java.awt.Point;
import java.util.Random;
import org.bukkit.Chunk;

/**
 *
 * @author valarnin
 */
public class CityBlock {

    private Chunk[][] chunks;
    private int leftX, rightX;
    private int topZ, bottomZ;
    private int xSize;
    private int zSize;
    private Direction direction;

    public CityBlock(int leftX, int rightX, int topZ, int bottomZ, Direction direction, Chunk startingChunk, Random random) {
        this.leftX = leftX;
        this.rightX = rightX;
        this.topZ = topZ;
        this.bottomZ = bottomZ;
        
        this.direction = direction;
        
        this.xSize = rightX - leftX + 1;
        this.zSize = bottomZ - topZ + 1;
        
        addChunk(startingChunk, random);
    }

    public boolean isAdjacent(int x, int z) {
        for (Chunk[] chunkX : chunks) {
            if (chunkX != null) {
                for (Chunk chunk : chunkX) {
                    if (chunk != null) {
                        if (Math.abs(chunk.getX() - x) <= 1 && Math.abs(chunk.getZ() - z) <= 1) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    boolean isRequired(int x, int z) {
        //If we're only 1x1, don't even bother checking for performance reasons
        if (leftX == rightX && topZ == bottomZ) {
            return false;
        }

        int xOffset = x - leftX;
        int zOffset = z - topZ;

        //If either of those are < 0, the chunk isn't within our bounds
        if (xOffset < 0 || zOffset < 0) {
            return false;
        }

        //Similarly, if either offset is greater than their corresponding size, they aren't within our bounds
        if (xOffset > xSize - 1 || zOffset > zSize - 1) {
            return false;
        }

        //If we've hit this point, the chunk falls within our boundries, so it's required
        return true;
    }
    
    public boolean isChunkAlreadyAdded(int x, int z) {
        return chunks[x - leftX] != null && chunks[x - leftX][z - topZ] != null;
    }

    public boolean addChunk(Chunk chunk, Random random) {
        if(!isChunkAlreadyAdded(chunk.getX(), chunk.getZ())) {
            if(chunks[chunk.getX() - leftX] == null) {
                chunks[chunk.getX() - leftX] = new Chunk[zSize];
            }
            chunks[chunk.getX() - leftX][chunk.getZ() - topZ] = chunk;
        }
        
        CityGen.GetCityGenerator().populate(this, random);
        
        return true;
    }

    public Direction getDirectionFromThis(int x, int z) {
        if(x < leftX) return Direction.EAST;
        if(x > rightX) return Direction.WEST;
        if(z < bottomZ) return Direction.SOUTH;
        if(z > topZ) return Direction.NORTH;
        return null;
    }
    
    public Direction getDirection() {
        return direction;
    }
    
    public int getTotalChunks() {
        return xSize * zSize;
    }

    public double getDistance(int x, int z) {
        Point point = new Point(x, z);
        double distance = Double.MAX_VALUE;
        for (Chunk[] chunkX : chunks) {
            if (chunkX != null) {
                for (Chunk chunk : chunkX) {
                    if (chunk != null) {
                        distance = Math.min(distance, point.distance(chunk.getX(), chunk.getZ()));
                    }
                }
            }
        }
        return distance;
    }
    
    public int getWidth() {
        return xSize;
    }
    
    public int getDepth() {
        return zSize;
    }
    
    public Chunk[][] getChunks() {
        return chunks;
    }
}
